package com.aggressionlabs.test;

import com.aggressionlabs.test.handler.HelloHandler;
import com.aggressionlabs.test.security.MongoLoginService;
import org.eclipse.jetty.security.ConstraintMapping;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.LoginService;
import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.security.authentication.BasicAuthenticator;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.security.Constraint;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.server.NCSARequestLog;
import org.eclipse.jetty.server.handler.RequestLogHandler;


import javax.xml.stream.XMLStreamException;
import java.util.ArrayList;
import java.util.Collections;

/**
 * Created by shirland on 11/29/14.
 */
public class JettyHelloWorld {

    private static final String USER_KEY = "ASSAULT_USERS";

    public static void main(String[] argv){

    	if ( argv.length != 1 ){
		System.err.println("Error!  Usage: <config file>");
		System.exit(1);
	}
		

        RunningConfig config = null;

        //load configs
        try {
            config = new RunningConfig(argv[0]);
        } catch (XMLStreamException e) {
            e.printStackTrace();
            System.exit(1);
        }

        int serverPort = config.getServerPort();


        Server s = new Server(serverPort);

        //LoginService loginService = new HashLoginService("MyRealm","/tmp/realm.properties");
        LoginService loginService = new MongoLoginService(config.getRealmName());
        s.addBean(loginService);

        //load configured handlers
        ArrayList<RunningConfig.HandlerConfig> handlerConfigs = config.getHandlerConfigs();

	HandlerCollection handlers = null;

        for (RunningConfig.HandlerConfig handler : handlerConfigs){

            if ( handlers == null )
                handlers = new HandlerCollection();
                
            ConstraintSecurityHandler security = new ConstraintSecurityHandler();
            Constraint constraint = new Constraint();
            constraint.setName("MyAuth");
            constraint.setAuthenticate(true);
            constraint.setRoles(new String[]{"user"});

            ConstraintMapping mapping = new ConstraintMapping();
            mapping.setPathSpec(handler.getContext());
            mapping.setConstraint(constraint);

            security.setConstraintMappings(Collections.singletonList(mapping));
            security.setAuthenticator(new BasicAuthenticator());
            security.setLoginService(loginService);

            ContextHandler context = new ContextHandler();
            context.setContextPath(handler.getContext());
            context.setResourceBase(".");
            Handler h = null;
            try {
                h = (Handler)ClassLoader.getSystemClassLoader().loadClass(handler.getClassName()).newInstance();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
                System.exit(1);
            } catch (InstantiationException e) {
                e.printStackTrace();
                System.exit(1);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
                System.exit(1);
            }

            context.setHandler(h);
            security.setHandler(context);

            //add to HandlerCollection
            handlers.addHandler(security);
        }

	//configure and add request log handler
	RequestLogHandler requestLogHandler = new RequestLogHandler();
	handlers.addHandler(requestLogHandler);

	NCSARequestLog requestLog = new NCSARequestLog(config.getLogDirectory() + "/web-yyyy_mm_dd-request.log");
	requestLog.setAppend(true);
	requestLog.setExtended(false);
	requestLogHandler.setRequestLog(requestLog);


	//add collection handler
        s.setHandler(handlers);

        try {
            s.start();
            s.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}
